package tech.aistar.day11;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 本类用来演示: A1aB2bC3c    .....  Z26z
 * 用Lock方式去实现一遍
 *
 * 控制线程的执行的顺序问题
 *
 * @author: success
 * @date: 2022/8/2 10:06 上午
 */
public class LockAwaitSignalDemo {
    private Lock lock = new ReentrantLock();

    //定义三个任务队列
    private Condition c1 = lock.newCondition();//大写
    private Condition c2 = lock.newCondition();//数字
    private Condition c3 = lock.newCondition();//小写

    //标记位 - 信号量
    private int count = 0;

    public void printUpper(){
        try {
            lock.lock();
            for (char i = 'A'; i <= 'Z' ; i++) {
                if(count!=0){
                    c1.await();//大写字母等待阻塞
                }
                System.out.print(i);
                count=1;
                //唤醒数字线程
                c2.signal();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void printNum(){
        try {
            lock.lock();
            for (int i = 1; i <=26 ; i++) {
                if(count!=1){
                    c2.await();
                }
                System.out.print(i);
                count=2;
                //唤醒小写字母
                c3.signal();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void printLower(){
        try {
            lock.lock();
            for (char i = 'a'; i <= 'z' ; i++) {
                if(count!=2){
                    c3.await();
                }
                System.out.print(i);
                count=0;
                //唤醒大写字母的
                c1.signal();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
class AwaitDemoTest{
    public static void main(String[] args) {
        LockAwaitSignalDemo demo = new LockAwaitSignalDemo();
        new Thread(()->demo.printUpper()).start();
        new Thread(()->demo.printNum()).start();
        new Thread(()->demo.printLower()).start();
    }
}
